<template>
  <QueryBar v-if="$slots.queryBar" @search="handleSearch" @reset="handleReset">
    <slot name="queryBar" />
  </QueryBar>

  <slot name="actionBar" />

  <div :class="isTitle ? 'box rel pt-50 mt-15 mb-15' : ''">
    <div class="title flex flex-cc flex-rb">
      <div v-if="isTitle">数据表</div>
      <slot name="title-right"></slot>
    </div>

    <n-data-table
      :remote="remote"
      :loading="loading"
      :scroll-x="scrollX"
      :columns="columns"
      :data="tableData"
      :row-key="(row) => row[rowKey]"
      v-model:checked-row-keys="rowKeys"
      @update:checked-row-keys="onChecked"
      v-bind="$attrs"
      v-if="!customTable"
    ></n-data-table>

    <div v-else>
      <div class="flex flex-center" style="min-height: 240px" v-if="loading">
        <n-spin size="large"></n-spin>
      </div>
      <slot name="customTable" :records="tableData" v-else></slot>
    </div>

    <div class="flex flex-cc flex-rr mt-15">
      <div class="mr-15">共{{ pagination.itemCount }}条</div>
      <n-pagination
        size="large"
        show-size-picker
        :page-count="pageCount"
        :page-sizes="[10, 20, 30, 40]"
        :page="pagination.page"
        :page-size="pagination.pageSize"
        @update:page="onPageChange"
        @update:page-size="onPageSizeChange"
      ></n-pagination>
    </div>
  </div>
</template>

<script setup>
import { NText } from 'naive-ui'
import { formatDateTime } from '@/utils'

const props = defineProps({
  remote: {
    type: Boolean,
    default: true,
  },
  isPagination: {
    type: Boolean,
    default: true,
  },
  scrollX: {
    type: Number,
    default: 1200,
  },
  rowKey: {
    type: String,
    default: 'id',
  },
  columns: {
    type: Array,
    required: true,
  },
  queryItems: {
    type: Object,
    default() {
      return {}
    },
  },
  extraParams: {
    type: Object,
    default() {
      return {}
    },
  },
  getData: {
    type: [Function, Object],
    required: false,
  },
  customTable: {
    type: Boolean,
    default: false,
  },
  isGet: {
    type: Boolean,
    default: false,
  },
  isTitle: {
    type: Boolean,
    default: true,
  },
})

const emit = defineEmits(['update:queryItems', 'onChecked'])
const loading = ref(false)
const initQuery = { ...props.queryItems }
const tableData = ref([])
const tableField = ref([])
const columns = ref([])
const pagination = reactive({
  page: 1,
  pageSize: 10,
})
const pageCount = ref(1)
const rowKeys = ref([])

async function handleQuery() {
  try {
    loading.value = true
    let paginationParams = {}
    // 如果非分页模式或者使用前端分页,则无需传分页参数
    if (props.isPagination && props.remote) {
      paginationParams = {
        current: pagination.page,
        size: pagination.pageSize,
      }
    }

    const params = {
      ...paginationParams,
      ...props.queryItems,
      ...props.extraParams,
    }

    if (params.disabilityInfoList) {
      params.disabilityInfoList = params.disabilityInfoList.join(',')
    }

    const { data } =
      typeof props.getData === 'function'
        ? await props.getData(params)
        : props.getData

    if (Array.isArray(data)) {
      const list = data || []
      list.forEach((v, i) => {
        v.tableIndex =
          i + 1 + (paginationParams.current - 1) * paginationParams.size
      })
      tableData.value = list

      // 静态列
      columns.value = props.columns
    } else {
      const list = data.records || []
      list.forEach((v, i) => {
        v.tableIndex =
          i + 1 + (paginationParams.current - 1) * paginationParams.size
      })
      tableData.value = list
      // tableField.value = data1.field || []

      if (tableField.value.length) {
        // 动态列
        columns.value = []

        tableField.value.map((c) => {
          if (c.show) {
            columns.value.push({
              title: c.value,
              key: c.key,
              width: c.width || 'auto',
              ellipsis: c.ellipsis ? { tooltip: true } : null,
              render:
                c.typeConfig.type === 'date'
                  ? (row) => {
                      return h(
                        NText,
                        {},
                        {
                          default: () =>
                            formatDateTime(row[c.key], c.typeConfig.format),
                        }
                      )
                    }
                  : c.typeConfig.type === 'number'
                  ? (row) => {
                      return h(
                        NText,
                        {},
                        {
                          default: () =>
                            Number(row[c.key] || 0).toFixed(c.typeConfig.round),
                        }
                      )
                    }
                  : null,
            })
          }
        })

        columns.value = [...columns.value, ...props.columns]
      } else {
        // 静态列
        columns.value = props.columns
      }
    }

    pagination.itemCount = data.total || tableData.value.length || 0
    pageCount.value = Math.ceil(pagination.itemCount / pagination.pageSize)
  } catch (error) {
    console.log(error)
    tableData.value = []
    pagination.itemCount = 0
  } finally {
    loading.value = false
  }
}
function handleSearch() {
  pagination.page = 1
  handleQuery()
}
function fillRecords(records = []) {
  tableData.value = records
  pagination.itemCount = records.length || 0
}
async function handleReset() {
  const queryItems = { ...props.queryItems }
  for (const key in queryItems) {
    queryItems[key] = ''
  }
  emit('update:queryItems', { ...queryItems, ...initQuery })
  await nextTick()
  pagination.page = 1
  handleQuery()
}
function onPageChange(currentPage) {
  pagination.page = currentPage
  if (props.remote) {
    handleQuery()
  }
}
function onPageSizeChange(currentPageSize) {
  pagination.page = 1
  pagination.pageSize = currentPageSize
  if (props.remote) {
    handleQuery()
  }
}
function onChecked(e) {
  if (columns.value.some((item) => item.type === 'selection')) {
    rowKeys.value = e
    emit('onChecked', e)
  }
}

defineExpose({
  handleSearch,
  handleQuery,
  handleReset,
  fillRecords,
  onChecked,
})
</script>

<style lang="scss" scoped></style>
